//============================================================================================
/**
 * @file	h_obst.c
 * @brief	ポケスロン競技：障害物競走　障害物
 * @author	Nozomu Saito
 *
 * モジュール名：H_OBST_
 */
//============================================================================================

#include "common.h"
#include "h_obst.h"

#include "pkthln_hurdle_cmn_def.h"

#define OBST_WIDTH	(64)
#define OBST_HEIGHT	(16)

#define CELL_HEIGHT	(8*7)	//セルの高さ（グラフィック依存）

#define OBST_HIT_OFS	(8)	//ヒット判定オフセットドット数（グラフィック依存）

typedef struct H_OBST_tag
{
	BOOL Valid;
	PKTHLN_ACT_PTR	ObjPtr;
	PKTHLN_ACT_PTR	AffObjPtr;
///	u16 Type;		//草・柵etc
	BOOL HitValid;
}H_OBST;

//--------------------------------------------------------------------------------------------
/**
 * @brief	まとめてアロケーション
 * @param	inNum		アロケート個数
 * @param	inHeapID	ヒープID
 *
 * @return	OBSTポインタ先頭アドレス
 */
//--------------------------------------------------------------------------------------------
H_OBST_PTR H_OBST_Alloc(const int inNum, const int inHeapID)
{
	H_OBST_PTR ptr;
	int size = sizeof(H_OBST) * inNum;
	ptr = sys_AllocMemory(inHeapID, size);
	MI_CpuClearFast(ptr, size);
	return ptr;
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	解放
 * @param	ptr		H_OBSTポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void H_OBST_Free(H_OBST_PTR ptr)
{
	sys_FreeMemoryEz(ptr);
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	H_OBSTポインタ取得
 *			アロケート時はまとめてとっているはずなので、サイズがわからないので、
 *			配列とインデックスを渡して、H_OBST構造体1つ分のポインタを取得する
 *
 * @param	pObstArray		H_OBSTポインタ（配列）
 * @param	inIndex			インデックス
 *
 * @return	H_OBSTポインタ
 */
//--------------------------------------------------------------------------------------------
H_OBST_PTR H_OBST_GetObstPtr(H_OBST_PTR pObstArray, const inIndex)
{
	return &pObstArray[inIndex];
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	OBJポインタセット
 * @param	ptr				H_OBSTポインタ
 * @param	obj_ptr			OBJポインタ	障害物
 * @param	aff_obj_ptr		OBJポインタ	ぶっ壊れＯＢＪ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void H_OBST_SetObjPtr(H_OBST_PTR ptr, PKTHLN_ACT_PTR obj_ptr, PKTHLN_ACT_PTR aff_obj_ptr)
{
	ptr->ObjPtr = obj_ptr;
	ptr->AffObjPtr = aff_obj_ptr;
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	アクティブ/非アクティブにする
 * @param	ptr			H_OBSTポインタ
 * @param	inActive	アクティブ状態にするかどうか
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void H_OBST_SetActive(H_OBST_PTR ptr, const u8 inActive)
{
	if (inActive){
		ptr->Valid = TRUE;
		ptr->HitValid = TRUE;
		PkthlnClAct_SetActive(ptr->ObjPtr, 1, 1);
		PkthlnClAct_SetActive(ptr->AffObjPtr, 1, 0);
		{
			CLACT_WORK_PTR act_ptr = PkthlnClAct_GetClActWorkPtr( ptr->AffObjPtr );
			CLACT_SetAnmFlag(act_ptr,0);
		}
	}else{
		ptr->Valid = FALSE;
		ptr->HitValid = FALSE;
		PkthlnClAct_SetActive(ptr->ObjPtr, 0, 0);
		PkthlnClAct_SetActive(ptr->AffObjPtr, 0, 0);
	}
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	障害物が有効常態かを調べる
 * @param	ptr			H_OBSTポインタ
 *
 * @return	BOOL		TRUE:有効	FALSE:無効
 */
//--------------------------------------------------------------------------------------------
BOOL H_OBST_IsValid(H_OBST_PTR ptr)
{
	return ptr->Valid;
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	障害物のヒット判定が有効かどうかを調べる
 * @param	ptr			H_OBSTポインタ
 *
 * @return	BOOL		TRUE:有効	FALSE:無効
 */
//--------------------------------------------------------------------------------------------
BOOL H_OBST_IsHitValid(H_OBST_PTR ptr)
{
	return ptr->HitValid;
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	障害物のヒット判定を無効にする
 * @param	ptr			H_OBSTポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void H_OBST_InvalidHit(H_OBST_PTR ptr)
{
	ptr->HitValid = FALSE;
	//画像変更
	{
		CLACT_WORK_PTR act_ptr = PkthlnClAct_GetClActWorkPtr( ptr->AffObjPtr );
		//バニッシュ
		PkthlnClAct_SetActive(ptr->ObjPtr, 1, 0);
		//ぶっ壊れＯＢＪに変更
		//表示
		PkthlnClAct_SetActive(ptr->AffObjPtr, 1, 1);
		//アニメ開始
		CLACT_SetAnmFlag(act_ptr,1);
		CLACT_AnmChg( act_ptr, 1);
	}
}


//--------------------------------------------------------------------------------------------
/**
 * 座標セット
 *
 * @param	ptr			アクターポインタ
 * @param	inVec		座標
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void H_OBST_SetPos(H_OBST_PTR ptr, VecFx32 *inVec)
{
	CLACT_WORK_PTR act_ptr = PkthlnClAct_GetClActWorkPtr( ptr->ObjPtr );
	CLACT_SetMatrix( act_ptr, inVec );
	act_ptr = PkthlnClAct_GetClActWorkPtr( ptr->AffObjPtr );
	CLACT_SetMatrix( act_ptr, inVec );
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	障害物動作メイン関数
 * @param	H_OBSTポインタ
 * @param	inSpeed		スピード
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void H_OBST_Move(H_OBST_PTR ptr, const int inSpeed)
{
	if (ptr->Valid){
		CLACT_WORK_PTR act_ptr, aff_act_ptr;
		VecFx32 vec;
//		OS_Printf("障害物の移動\n");
		act_ptr = PkthlnClAct_GetClActWorkPtr( ptr->ObjPtr );
		aff_act_ptr = PkthlnClAct_GetClActWorkPtr( ptr->AffObjPtr );
		vec =  *CLACT_GetMatrix( act_ptr );
		vec.y += (FX32_ONE*inSpeed);
		CLACT_SetMatrix( act_ptr, &vec );
		CLACT_SetMatrix( aff_act_ptr, &vec );


		if ( vec.y >= FX32_ONE*(192*2+DISP_BLANK+CELL_HEIGHT) ){
//			OS_Printf("寿命\n");
			H_OBST_SetActive(ptr, 0);
		}
	}
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	ヒット矩形取得
 * @param	ptr			H_OBSTポインタ
 * @param	outHitRect	ヒット矩形
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void H_OBST_GetHitRect(H_OBST_PTR ptr, HIT_RECT *outHitRect)
{
	CLACT_WORK_PTR act_ptr = PkthlnClAct_GetClActWorkPtr(ptr->ObjPtr);
	//座標取得
	s16 w,h;
	const VecFx32 *vec;
	vec = CLACT_GetMatrix(act_ptr);

	w = OBST_WIDTH/2;
	h = OBST_HEIGHT/2;

	outHitRect->W = OBST_WIDTH;
	outHitRect->H = OBST_HEIGHT;
	outHitRect->X = (vec->x / FX32_ONE) - w;
	outHitRect->Y = (vec->y / FX32_ONE) - h - OBST_HIT_OFS;

}
